package com.wiscamp.ninechapters.panels.infrastructure.repositories;


import com.wiscamp.ninechapters.panels.domain.entities.Permission;
import com.wiscamp.ninechapters.panels.domain.repositories.PermissionRepository;
import com.wiscamp.ninechapters.panels.infrastructure.converters.PermissionConverter;
import com.wiscamp.ninechapters.panels.infrastructure.mappers.PermissionMapper;
import com.wiscamp.ninechapters.panels.infrastructure.mappers.PermissionViewMapper;
import com.wiscamp.ninechapters.panels.infrastructure.po.PermissionPO;
import com.wiscamp.ninechapters.panels.infrastructure.views.PermissionView;
import cube.ddd.aspect.HandleDataException;
import cube.ddd.common.query.PagedObjects;
import cube.ddd.common.query.PagedQuery;
import cube.ddd.utils.PersistenceUtils;
import org.springframework.stereotype.Repository;

import java.util.Collection;

@Repository
public class PermissionRepositoryImpl implements PermissionRepository {

    private final PermissionMapper permissionMapper;

    private final PermissionViewMapper permissionViewMapper;

    public PermissionRepositoryImpl(PermissionMapper permissionMapper, PermissionViewMapper permissionViewMapper) {
        this.permissionMapper = permissionMapper;
        this.permissionViewMapper = permissionViewMapper;
    }

    private PermissionPO getPermissionPO(long permissionId) {
        return PersistenceUtils.findById(permissionId, permissionMapper::findById);
    }

    @HandleDataException
    public Permission getPermission(long permissionId) {
        return PersistenceUtils.findEntityById(permissionId, permissionViewMapper::findById,
                PermissionConverter.Instance::toPermissionByView);
    }

    @HandleDataException
    public Permission getPermissionByCode(long appId, String permissionCode) {
        return PersistenceUtils.getEntityByIdAndText(appId, permissionCode, permissionViewMapper::findByPermissionCode,
                PermissionConverter.Instance::toPermissionByView);
    }

    @HandleDataException
    public Collection<Permission> getPermissionsByGroup(long appId, String permissionGroup) {
        return PersistenceUtils.getEntitiesByIdAndText(appId, permissionGroup, permissionViewMapper::findListByPermissionGroup,
                PermissionConverter.Instance::toPermissionByView);
    }

    @HandleDataException
    public Collection<Permission> getPermissionsByName(long appId, String permissionName) {
        return PersistenceUtils.getEntitiesByIdAndText(appId, permissionName, permissionViewMapper::findListByPermissionName,
                PermissionConverter.Instance::toPermissionByView);
    }

    @HandleDataException
    public Collection<Permission> getPermissionsByIds(Collection<Long> permissionIds) {
        return PersistenceUtils.getEntitiesByIds(permissionIds, permissionViewMapper::findAllById,
                PermissionConverter.Instance::toPermissionByView);
    }

    @HandleDataException
    public PagedObjects<Permission> getPermissionsByQuery(PagedQuery query) {
        PagedObjects<PermissionView> pagedObjects = PersistenceUtils.getPersistenceObjectsByQuery(query, permissionViewMapper::findAll);
        return PersistenceUtils.convertPagedObjects(pagedObjects, PermissionConverter.Instance::toPermissionByView);
    }

    @HandleDataException
    public Permission savePermission(Permission permission) {
        if (permission.getPermissionId() <= 0) {
            return PersistenceUtils.createEntity(permission, permissionMapper::saveAndFlush,
                    PermissionConverter.Instance::toPermissionPO, PermissionConverter.Instance::toPermission);
        } else {
            var existedPO = getPermissionPO(permission.getPermissionId());
            if (existedPO == null) existedPO = new PermissionPO();
            return PersistenceUtils.updateEntity(permission, existedPO, permissionMapper::saveAndFlush,
                    PermissionConverter.Instance::toPermissionPO, PermissionConverter.Instance::toPermission);
        }
    }

}
